S3にファイルが作成されたときにSystems Manager Run Commandを実行するLambda関数を作成してみた
S3にファイルが作成されたときにEC2にコピーするLambda関数を作成したのでブログに残します。
作成したLambda関数
以下のコードを作成しました。
from datetime import datetime import boto3 import os ssm = boto3.client('ssm') instance_id = os.environ['instance_id'] now = datetime.now() file_name = 'file_name' + now.strftime('%Y%m%d%H%M%S') def lambda_handler(event, context): bucket = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] response = ssm.send_command( InstanceIds=[instance_id], DocumentName='AWS-RunShellScript', Parameters={ 'commands': [ f'aws s3 cp s3://{bucket}/{key} /home/ec2-user/{file_name}' ], 'executionTimeout': ['3600'], } )
こちらはS3にファイルが作成されるとAWS Systems Manager Run CommandでAWS-RunShellScriptドキュメントを実行します。
AWS-RunShellScriptはSystems Managerのマネージドノードに対してコマンドを実行することができるものになります。
今回は「aws s3 cp」を実行してS3で作成されたファイルをec2-userのホームディレクトリにfile_nameyyyymmddhhmmssというファイル名で作成します。
send_command
デプロイ
Lambdaの作成はAWS SAMを使用しました。
コマンドを実行する環境はCloudShellを使用しています。
今回Pythonの3.9を使用しているので以下のコマンドを実行してPython 3.9が使用できるようにします。
sudo yum install gcc openssl-devel bzip2-devel libffi-devel -y wget https://www.python.org/ftp/python/3.9.17/Python-3.9.17.tgz tar xzf Python-3.9.17.tgz cd Python-3.9.17 ./configure --enable-optimizations --prefix=$HOME/.local sudo make altinstall cd .. sudo rm -rf Python-3.9.17 Python-3.9.17.tgz
作成したtemplate.yamlは以下になります。
今回は既にSystems ManagerにマネージドノードのEC2が追加されている前提で進めます。
マネージドノードについてはこちらのドキュメントをご確認ください。
Lambda関数以外にもS3とIAMロールも一緒に作成をしています。
AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: SSM RunCommand Parameters: instanceid: Type: String Resources: FunctionIamPolicy: Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: "logs:CreateLogGroup" Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" - Effect: Allow Action: - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/function-ssm-runcommand-${AWS::Region}:*" - Effect: Allow Action: - "ssm:SendCommand" Resource: "*" ManagedPolicyName: !Sub "policy-lambda-ssm-runcommand-${AWS::Region}" FunctionIamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Action: "sts:AssumeRole" Effect: Allow Principal: Service: lambda.amazonaws.com ManagedPolicyArns: - !Ref FunctionIamPolicy RoleName: !Sub "role-lambda-ssm-runcommand-${AWS::Region}" Tags: - Key: Name Value: !Sub "role-lambda-ssm-runcommand-${AWS::Region}" S3: Type: AWS::S3::Bucket DependsOn: Function Properties: BucketName: !Sub s3-${AWS::AccountId} BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 NotificationConfiguration: LambdaConfigurations: - Event: "s3:ObjectCreated:*" Function: !GetAtt Function.Arn Function: Type: AWS::Serverless::Function Properties: CodeUri: function/ Environment: Variables: instance_id: !Ref instanceid Events: S3: Properties: Bucket: !Ref S3 Events: s3:ObjectCreated:* Type: S3 FunctionName: !Sub function-ssm-runcommand-${AWS::Region} Handler: lambda_function.lambda_handler Role: !GetAtt FunctionIamRole.Arn Runtime: python3.9 Timeout: 900
Lambda関数のコードとtemplate.yamlは私のGitHubリポジトリに保管しています。
今回はそこからクローンしてデプロイする手順を記載します。
以下のコマンドを実行します。
git clone https://github.com/Kobayashi-Riku0226/lambda_repository.git cd lambda_repository/ssm_runcommand sam build sam deploy --stack-name スタック名 --s3-bucket CloudFormationテンプレートを格納するS3バケット --capabilities CAPABILITY_NAMED_IAM --parameter-overrides instanceid=ファイルをコピーするEC2インスタンス ID
動作確認
動作確認は上記のデプロイで作成されたS3バケットにファイルをputします。
以下のコマンドをCloudShellで実行してください。
echo "test file" > test.txt aws s3 cp ./test.txt s3://S3バケット名
実行後、ファイルをコピーするEC2インスタンスにSSHやSession Managerで接続してec2-userのホームディレクトリを見るとファイルが作成されていることが確認できます。
ls -la /home/ec2-user/ total 20 drwx------. 3 ec2-user ec2-user 136 Jun 29 08:02 . drwxr-xr-x. 4 root root 38 Jun 29 06:54 .. -rw-r--r--. 1 ec2-user ec2-user 18 Jan 28 22:29 .bash_logout -rw-r--r--. 1 ec2-user ec2-user 141 Jan 28 22:29 .bash_profile -rw-r--r--. 1 ec2-user ec2-user 492 Jan 28 22:29 .bashrc drwx------. 2 ec2-user ec2-user 29 Jun 28 14:22 .ssh -rw-r--r--. 1 root root 10 Jun 29 08:02 file_name20230629080257
さいごに
今回はS3にファイルが作成されたときにEC2にファイルをコピーするLambda関数を作成してみました。
設定自体はシンプルなのでS3のイベント起因でコマンドを実行したいみたいな時の参考になればと思います。